package org.hawk.gwt.ppc.parser.impl;

import org.hawk.gwt.ppc.parser.NoSuchTokenException;
import org.hawk.gwt.ppc.parser.Token;
import org.hawk.gwt.ppc.utils.PreprocessorException;

/**
 * Common implementation for tokens source.
 * 
 * @author alex.bereznevatiy@gmail.com
 *
 */
abstract class AbstractTokenSource implements TokenSource {
	
	Token current;
	private Token next;
	private boolean eof;
	
	/**
	 * Initializes this token source.
	 * Should be call before start tokenization.
	 * @throws PreprocessorException
	 */
	void init() throws PreprocessorException {
		next = readNext();
	}

	/* (non-Javadoc)
	 * @see org.hawk.gwt.ppc.parser.impl.TokenSource#current()
	 */
	public Token current() {
		if (current == null) {
			throw new NoSuchTokenException();
		}
		return current;
	}

	/* (non-Javadoc)
	 * @see org.hawk.gwt.ppc.parser.impl.TokenSource#hasNext()
	 */
	public boolean hasNext() {
		return next != null;
	}

	/* (non-Javadoc)
	 * @see org.hawk.gwt.ppc.parser.impl.TokenSource#next()
	 */
	public Token next() throws PreprocessorException {
		if (next == null) {
			throw new NoSuchTokenException();
		}
		current = next;
		next = readNext();
		return current;
	}

	/* (non-Javadoc)
	 * @see org.hawk.gwt.ppc.parser.impl.TokenSource#eof()
	 */
	public void eof() {
		this.eof  = true;
	}

	/* (non-Javadoc)
	 * @see org.hawk.gwt.ppc.parser.impl.TokenSource#isEof()
	 */
	public boolean isEof() {
		return eof;
	}

	/**
	 * @return next token in the implementation-specific manner.
	 * @throws PreprocessorException
	 */
	Token readNext() throws PreprocessorException {
		throw new PreprocessorException("Not implemented");
	}
}
